﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using FineUIMvc;

namespace BoYuan.FineUIMvcWeb.Code
{
    public class BaseTree : System.IDisposable
    {
        public BaseTree(){}

        #region  创建tree

        /// <summary>
        /// 创建tree
        /// </summary>
        /// <param name="nodes">tree控件note集合</param>
        /// <param name="dt">数据集</param>
        /// <param name="nodeText">node显示的字段</param>
        /// <param name="nodeIcon">node图标字段</param>
        /// <param name="fontIcon">字体图标</param>
        /// <param name="nodePid">node父id字段</param>
        /// <param name="expanded">是否展开节点</param>
        /// <param name="enableClickEvent">是否单击节点回发</param>
        /// <param name="enableCheckBox">是否采用复选框</param>
        /// <param name="enableCheckEvent">是否启用复选框回发事件</param>
        /// <param name="navigateUrl">链接地址</param>
        /// <param name="allowShowColumn">控制是否显示节点的字段名称</param>
        /// <param name="sortColumn">排序字段</param>
        public static void CreateTree(IList<TreeNode> nodes, DataTable dt, string nodeText, string nodeIcon, string fontIcon, string nodePid,
            string navigateUrl, bool expanded = true, bool enableClickEvent = false, bool enableCheckBox = false, bool enableCheckEvent = false, string allowShowColumn = "", string sortColumn = "sort asc")
        {

            string showStr = string.Empty;
            if (allowShowColumn.Length > 0)
            {
                showStr = " and " + allowShowColumn + ">0 ";
            }

            DataView dv = dt.DefaultView;
            dv.Sort = sortColumn;//相当于Order By
            dv.RowFilter = nodePid + "=0 " + showStr;//相当于Where

            
            TreeNode node;

            foreach (DataRow dr in dv.ToTable().Rows)
            {
                node = AddTreeNode(dr, nodeText, nodeIcon, fontIcon, expanded,  enableCheckBox,  navigateUrl);

                nodes.Add(node);

                ResolveSubTree(dt, dr["id"].ToString(), node, nodeText, nodeIcon, fontIcon, nodePid, expanded, enableClickEvent, enableCheckBox, enableCheckEvent, navigateUrl, allowShowColumn);
            }


        }


        /// <summary>
        /// 循环子节点
        /// </summary>
        /// <param name="dt">数据集</param>
        /// <param name="parentId">父编号</param>
        /// <param name="treeNode"></param>
        /// <param name="nodeText">node显示的字段</param>
        /// <param name="nodeIcon">node图标字段</param>
        /// <param name="fontIcon">字体图标</param>
        /// <param name="nodePid">node父id字段</param>
        /// <param name="expanded">是否展开节点</param>
        /// <param name="enableClickEvent">是否点击节点回发</param>
        /// <param name="enableCheckBox">是否采用复选框</param>
        /// <param name="enableCheckEvent">是否启用复选框回发事件</param>
        /// <param name="navigateUrl">链接地址</param>
        ///  <param name="allowShowColumn">控制是否显示节点的字段名称</param>
        private static void ResolveSubTree(DataTable dt, string parentId, TreeNode treeNode, string nodeText, string nodeIcon, string fontIcon, string nodePid, bool expanded, bool enableClickEvent, bool enableCheckBox, bool enableCheckEvent, string navigateUrl, string allowShowColumn)
        {
            string showStr = string.Empty;
            if (allowShowColumn.Length > 0)
            {
                showStr = " and " + allowShowColumn + ">0 ";
            }
            DataView dv = dt.DefaultView;
            dv.Sort = "sort asc";//相当于Order By
            dv.RowFilter = nodePid + "=" + parentId + " " + showStr;//相当于Where

            TreeNode node;
            foreach (DataRow dr in dv.ToTable().Rows)
            {
                node = AddTreeNode(dr, nodeText, nodeIcon, fontIcon, expanded,  enableCheckBox,  navigateUrl);
                treeNode.Nodes.Add(node);
                ResolveSubTree(dt, dr["id"].ToString(), node, nodeText, nodeIcon, fontIcon, nodePid, expanded, enableClickEvent, enableCheckBox, enableCheckEvent, navigateUrl, allowShowColumn);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dr"></param>
        /// <param name="nodeText"></param>
        /// <param name="nodeIcon"></param>
        /// <param name="fontIcon">字体图标</param>
        /// <param name="expanded"></param>
        /// <param name="enableCheckBox"></param>
        /// <param name="navigateUrl"></param>
        /// <returns></returns>
        private static TreeNode AddTreeNode(DataRow dr, string nodeText, string nodeIcon, string fontIcon, bool expanded, bool enableCheckBox,  string navigateUrl)
        {
            TreeNode node = new TreeNode();
            node.NodeID = dr["id"].ToString();
            node.Text = dr[nodeText].ToString();

            if (dr[nodeIcon].ToString().Length > 0)//默认 图标比字体图标优先级高
                node.IconUrl = "/" + dr[nodeIcon].ToString();
            else if (dr[fontIcon].ToString().Length > 0)//如果字体图标有值
                node.IconFont = (IconFont)Enum.Parse(typeof(IconFont), dr[fontIcon].ToString());

           
            node.EnableCheckBox = enableCheckBox;
            
            node.Expanded = expanded;
            //node.CssClass = "layui";

            string tempurl = dr[navigateUrl].ToString();
            if (!string.IsNullOrEmpty(tempurl))
                node.NavigateUrl = tempurl;
            return node;
        }

        #endregion

        #region  创建accordion

        /// <summary>
        /// 创建accordion
        /// </summary>
        /// <param name="accordion"></param>
        /// <param name="dt"></param>
        /// <param name="title"></param>
        /// <param name="iconUrl"></param>
        /// <param name="fontIcon">字体图标</param>
        /// <param name="pidcolumn"></param>
        /// <param name="navigateUrl"></param>
        ///  <param name="allowShowColumn">控制是否显示节点的字段名称</param>
        public static void CreateAccordion(Accordion accordion, DataTable dt, string title, string iconUrl, string fontIcon, string pidcolumn, string navigateUrl, string allowShowColumn = "", string sortColumn = "sort asc")
        {
            string showStr = string.Empty;
            if (allowShowColumn.Length > 0)
            {
                showStr = " and " + allowShowColumn + ">0 ";
            }

            DataView dv = dt.DefaultView;
            dv.Sort = sortColumn;//相当于Order By
            dv.RowFilter = pidcolumn + "=0 " + showStr;//相当于Where

            foreach (DataRow dr in dv.ToTable().Rows)
            {
                AccordionPane pane = new AccordionPane();
                accordion.Panes.Add(pane);
                pane.Title = dr[title].ToString();
                pane.IconUrl = dr[iconUrl].ToString();
                pane.ShowBorder = false;

                //创建该节点下的菜单目录,并将该手风琴节点的ID作为下属菜单的父节点                
                ResolveSubTree(dt, dr["ID"].ToString(), title, iconUrl, fontIcon, pidcolumn, navigateUrl, pane, allowShowColumn);
            }
        }

        /// <summary>
        /// 循环子节点
        /// </summary>
        /// <param name="dt">数据集</param>
        /// <param name="parentId">父编号</param>
        /// <param name="nodeText">node显示的字段</param>
        /// <param name="nodeIcon">node图标字段</param>
        /// <param name="nodePid">node父id字段</param>
        /// <param name="navigateUrl">链接地址</param>
        /// <param name="pane">要加载到Accordion</param>
        ///  <param name="allowShowColumn">控制是否显示节点的字段名称</param>
        private static void ResolveSubTree(DataTable dt, string parentId, string nodeText, string nodeIcon, string fontIcon, string nodePid, string navigateUrl, AccordionPane pane, string allowShowColumn, string sortColumn = "sort asc")
        {
            string showStr = string.Empty;
            if (allowShowColumn.Length > 0)
            {
                showStr = " and " + allowShowColumn + ">0 ";
            }

            DataView dv = dt.DefaultView;
            dv.Sort = sortColumn;//相当于Order By
            dv.RowFilter = nodePid + "=" + parentId + " " + showStr;//相当于Where


            FineUIMvc.Tree tree = new FineUIMvc.Tree();
            pane.Items.Add(tree);
            tree.ShowBorder = false;
            tree.ShowHeader = false;
            tree.AutoScroll = false;
            //tree.EnableArrows = true;

            TreeNode TN;
            foreach (DataRow dr in dv.ToTable().Rows)
            {
                TN = new TreeNode();
                TN.NodeID = dr["id"].ToString();
                TN.Text = dr[nodeText].ToString();
                TN.IconUrl = dr[nodeIcon].ToString();
                if (!string.IsNullOrEmpty(navigateUrl))
                    TN.NavigateUrl = dr[navigateUrl].ToString();
                tree.Nodes.Add(TN);

                ResolveSubTree(dt, dr["ID"].ToString(), TN, nodeText, nodeIcon, fontIcon, nodePid, true, false, false, false, navigateUrl, allowShowColumn);
            }
        }
        #endregion

        #region 循环展开节点(用try接此方法)
        /// <summary>
        /// 递归调用父节点，并使节点展开(注意会有找不到父节点的异常)
        /// </summary>
        /// <param name="node"></param>
        public static void SetTreeExpanded(TreeNode node)
        {
            TreeNode newNode = node.ParentNode;
            newNode.Expanded = true;
            SetTreeExpanded(newNode);
        }
        #endregion

        #region 重新设置每个节点的图标
        /// <summary>
        /// 重新设置每个节点的图标
        /// </summary>
        /// <param name="nodes"></param>
        public static void ResolveTreeNode(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Nodes.Count == 0)
                {
                    if (!String.IsNullOrEmpty(node.NavigateUrl))
                    {
                        node.IconUrl = GetIconForTreeNode(node.NavigateUrl);
                    }
                }
                else
                {
                    ResolveTreeNode(node.Nodes);
                }
            }
        }
        #endregion

        #region 根据链接地址返回相应的图标
        /// <summary>
        /// 根据链接地址返回相应的图标
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetIconForTreeNode(string url)
        {
            string iconUrl = "~/res/images/filetype/vs_unknow.png";
            url = url.ToLower();
            int lastDotIndex = url.LastIndexOf('.');
            string fileType = url.Substring(lastDotIndex + 1);

            switch (fileType)
            {
                case "txt":
                    iconUrl = "~/res/images/filetype/vs_txt.png";
                    break;
                case "aspx":
                    iconUrl = "~/res/images/filetype/vs_aspx.png";
                    break;
                case "htm":
                //break;
                case "html":
                    iconUrl = "~/res/images/filetype/vs_htm.png";
                    break;
            }

            return iconUrl;
        }
        #endregion

        #region 实例化方法
        public BaseTree(FineUIMvc.Tree treeCtrl)
        {
            _tree = treeCtrl;
        }

        /// <summary>
        /// 创建tree
        /// </summary>
        public void CreateTree()
        {

            DataRow[] drParent = TreeDataSet.Tables[0].Select(ColumnNodePid + "=0");

            TreeNode node;

            foreach (DataRow dr in drParent)
            {
                node = AddTreeNode(dr);

                _tree.Nodes.Add(node);

                ResolveSubTree(dr["id"].ToString(), node);
            }
        }

        public void Dispose()
        {
            //释放数据源资源
            TreeDataSet.Dispose();
        }

        /// <summary>
        /// 循环子节点
        /// </summary>
        private void ResolveSubTree(string parentId, TreeNode treeNode)
        {
            DataRow[] drParent = TreeDataSet.Tables[0].Select(ColumnNodePid + "=" + parentId + "");

            TreeNode node;
            foreach (DataRow dr in drParent)
            {
                node = AddTreeNode(dr);
                treeNode.Nodes.Add(node);
                ResolveSubTree(dr["id"].ToString(), node);
            }
        }

        private TreeNode AddTreeNode(DataRow dr)
        {
            TreeNode node = new TreeNode();
            node.NodeID = dr[ColumnNodeId].ToString();
            node.Text = dr[ColumnNodeText].ToString();

            if (dr[ColumnNodeIcon].ToString().Length > 0)
                node.IconUrl = "/" + dr[ColumnNodeIcon].ToString();

            node.EnableCheckBox = EnableCheckBox;
            node.Expanded = Expanded;

            if (EnableCheckBox)
            {
                //判断node.NodeID是否在checkValue中
                if ((CheckValue).Contains(node.NodeID))
                {
                    node.Checked = true;
                }
                else
                {
                    node.Checked = Checked;
                }
            }

            string tempurl = dr[ColumnNavigateUrl].ToString();
            if (!string.IsNullOrEmpty(tempurl))
                node.NavigateUrl = tempurl;

            return node;
        }

        #region 属性

        private FineUIMvc.Tree _tree;

        /// <summary>
        /// 显示tree文本的字段
        /// </summary>
        public string ColumnNodeText { get; set; }

        /// <summary>
        /// 关联tree id的字段
        /// </summary>
        public string ColumnNodeId { get; set; }

        /// <summary>
        /// 关联tree 图标的字段
        /// </summary>
        public string ColumnNodeIcon { get; set; }

        /// <summary>
        /// 关联tree 父id的字段
        /// </summary>
        public string ColumnNodePid { get; set; }

        /// <summary>
        /// 关联tree 链接的字段
        /// </summary>
        public string ColumnNavigateUrl { get; set; }

        /// <summary>
        /// treenode 是否展开
        /// </summary>
        public bool Expanded { get; set; } = true;

        /// <summary>
        /// treenode 是否选中
        /// </summary>
        public bool Checked { get; set; } = false;

        /// <summary>
        /// treenode 是否有多选框
        /// </summary>
        public bool EnableCheckBox { get; set; } = false;

        /// <summary>
        /// treenode 是否有多选事件
        /// </summary>
        public bool EnableCheckEvent { get; set; } = false;


        /// <summary>
        /// treenode 是否有点击事件
        /// </summary>
        public bool EnableClickEvent { get; set; } = false;

        /// <summary>
        /// treenode 是否折叠事件
        /// </summary>
        public bool EnableCollapseEvent { get; set; } = false;

        /// <summary>
        /// treenode 是否展开事件
        /// </summary>
        public bool EnableExpandEvent { get; set; } = false;


        /// <summary>
        /// 选中值
        /// </summary>
        public IList CheckValue { get; set; }

        /// <summary>
        /// 绑定数据源
        /// </summary>
        public DataSet TreeDataSet { get; set; }

        #endregion




        #endregion



    }
}